package com.sci.filter;

import com.sci.entity.CommonResult;
import com.sci.util.JwtTokenUtil;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
public class JwtAuthFilter extends AbstractGatewayFilterFactory<JwtAuthFilter.Config> {

    private final JwtTokenUtil jwtTokenUtil;

    public JwtAuthFilter(JwtTokenUtil jwtTokenUtil) {
        super(Config.class);
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @Override
    public String name() {
        return "JwtAuth";
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();

            // 检查是否在排除路径中
            String path = request.getPath().toString();
            if (config.getExcludePaths() != null &&
                    config.getExcludePaths().stream().anyMatch(excludePath ->
                            path.startsWith(excludePath) || path.equals(excludePath))) {
                return chain.filter(exchange);
            }

            // 从Cookie或Header获取token
            String token = extractToken(request);
            System.out.println("Extracted token: " + token);

            if (!StringUtils.hasText(token)) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                CommonResult<String> result = new CommonResult<>(401, "未经授权: 缺少有效的鉴权信息", null);
                return response.writeWith(Mono.just(response.bufferFactory()
                        .wrap(result.toString().getBytes())));
            }

            try {
                // 验证Token
                if (!jwtTokenUtil.validateToken(token)) {
                    System.err.println("Token validation failed");
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                    CommonResult<String> result = new CommonResult<>(401, "无效的令牌", null);
                    return response.writeWith(Mono.just(response.bufferFactory()
                            .wrap(result.toString().getBytes())));
                }

                // 获取用户ID
                String userId = jwtTokenUtil.getUserIdFromToken(token);
                System.out.println("Token validated successfully for user: " + userId);

                // 将用户信息添加到请求头
                ServerHttpRequest mutatedRequest = request.mutate()
                        .header("X-User-Id", userId)
                        .build();

                return chain.filter(exchange.mutate().request(mutatedRequest).build());
            } catch (Exception e) {
                System.err.println("Token validation error: " + e.getMessage());
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                CommonResult<String> result = new CommonResult<>(401, e.getMessage(), null);
                return response.writeWith(Mono.just(response.bufferFactory()
                        .wrap(result.toString().getBytes())));
            }
        };
    }

    private String extractToken(ServerHttpRequest request) {
        // 从Cookie获取
        List<String> cookies = request.getHeaders().get("Cookie");
        if (cookies != null) {
            for (String cookie : cookies) {
                String[] parts = cookie.split(";");
                for (String part : parts) {
                    if (part.trim().startsWith("access_token=")) {
                        String token = part.trim().substring("access_token=".length());
                        System.out.println("Extracted Token from Cookie: " + token);
                        return token;
                    }
                }
            }
        }

        // 从Authorization头获取
        String authHeader = request.getHeaders().getFirst("Authorization");
        if (StringUtils.hasText(authHeader) && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            System.out.println("Extracted Token from Header: " + token);
            return token;
        }

        System.out.println("No Token Found");
        return null;
    }

    public static class Config {
        private List<String> excludePaths;

        public List<String> getExcludePaths() {
            return excludePaths;
        }

        public void setExcludePaths(List<String> excludePaths) {
            this.excludePaths = excludePaths;
        }
    }
}